﻿using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using Autodesk.Revit.DB;
using Gpc;
using YJKArch.Utils;
using HYRevitCode.RevitTopologySuite.GPCAdapter;

namespace YJKArch.EditFloor
{
	public class GpcPolygonController
	{
		public static CurveArrArray ClipAreas(ref CurveArray loop1, CurveArray loop2)
		{
			Polygon polygon = GpcPolygonController.ConstructPolygon(loop1);
			Polygon clipPolygon = GpcPolygonController.ConstructPolygon(loop2);
			CurveArrArray result;
			try
			{
				IPolygon polygon2 = polygon.ClipPolygon(clipPolygon, ClipOp.Diff);
                List<XPoint2D> polygonPoints = HYRevitCode.RevitTopologySuite.GPCAdapter.GpcPolygonController.GetPolygonPoints(polygon2 as Polygon, ContourType.Filled);
                HYRevitCode.RevitTopologySuite.GPCAdapter.GpcPolygonController.GetPolygonPoints(polygon2 as Polygon, ContourType.Hollow);
				if (polygonPoints.Count < 3)
				{
					result = null;
				}
				else
				{
                    List<List<Curve>> list = HYRevitCode.RevitTopologySuite.GPCAdapter.GpcPolygonController.ConvertPointToAreaCurves(polygonPoints);
					CurveArrArray curveArrArray = new CurveArrArray();
					foreach (List<Curve> list2 in list)
					{
						try
						{
							if (Math.Abs(GpcPolygonController.CalculateArea(list2)) < 1.0)
							{
								continue;
							}
						}
						catch
						{
						}
						CurveArray curveArray = new CurveArray();
						foreach (Curve curve in list2)
						{
							curveArray.Append(curve);
						}
						curveArrArray.Append(curveArray);
					}
					loop1 = curveArrArray.get_Item(curveArrArray.Size - 1);
					result = curveArrArray;
				}
			}
			catch (Exception)
			{
				result = null;
			}
			return result;
		}

		public static bool AnalyzeClipAreas(CurveArray loop1, CurveArray loop2)
		{
			try
			{
				Polygon polygon = GpcPolygonController.ConstructPolygon(loop1);
				Polygon polygon2 = GpcPolygonController.ConstructPolygon(loop2);
				GraphicsPath graphicsPath = polygon.ClipPolygon(polygon2, ClipOp.Diff).ToGraphicsPath(ContourType.All, GraphicsPathType.Lines);
				GraphicsPath graphicsPath2 = polygon2.ClipPolygon(polygon, ClipOp.Diff).ToGraphicsPath(ContourType.All, GraphicsPathType.Lines);
				if (graphicsPath.PointCount > 1 && graphicsPath2.PointCount > 1)
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private static Polygon ConstructPolygon(CurveArray loop)
		{
			new Polygon();
			List<Curve> list = new List<Curve>();
			foreach (object obj in loop)
			{
				if (obj is Curve)
				{
					list.Add(obj as Curve);
				}
			}
            return HYRevitCode.RevitTopologySuite.GPCAdapter.GpcPolygonController.ConstructPolygon(list, null);
		}

		private static double CalculateArea(List<Curve> curves)
		{
			List<double> list = new List<double>();
			List<double> list2 = new List<double>();
			foreach (Curve curve in curves)
			{
				XYZ endPoint = curve.GetEndPoint(0);
				list.Add(endPoint.X);
				list2.Add(endPoint.Y);
			}
			return Geometry.AoArea(list.Count, list.ToArray(), list2.ToArray());
		}
	}
}
